﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace PokeTD
{
    class LoginScreen : GameScreen
    {
        ContentManager content;
        Texture2D backgroundTexture;
        SpriteFont font;
        SpriteFont smallfont;

        Texture2D checkboxChecked;
        Texture2D checkboxUnchecked;
        Texture2D backgroundLayer;

        float blink_delay;
        bool blink_state;
        const int maxlen = -1;

        bool alt_pressed = false;

        bool buttonOkHover = false;
        bool buttonCancelHover = false;

        string user_mail;
        string user_pass;
        bool keep_login;
        int activated_field = 0;

        InputAction inputExit;

        public LoginScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);

            inputExit = new InputAction(
                new Buttons[] { Buttons.B, Buttons.Back },
                new Keys[] { Keys.Escape },
                true);

            InputEvent.CharEntered += new CharEnteredHandler(InputEvent_CharEntered);
            InputEvent.KeyDown += new KeyEventHandler(InputEvent_KeyDown);
            InputEvent.KeyUp += new KeyEventHandler(InputEvent_KeyUp);
        }

        void InputEvent_KeyUp(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.LeftAlt:
                case Keys.RightAlt:
                case (Keys)18: // alt??
                    alt_pressed = false;
                    break;
            }
        }

        void InputEvent_KeyDown(object sender, KeyEventArgs e)
        {
            if (activated_field == -1) return;

            string s = (activated_field == 0) ? user_mail : user_pass;

            KeyboardState k = Keyboard.GetState();

            switch (e.KeyCode)
            {
                case Keys.LeftAlt:
                case Keys.RightAlt:
                case (Keys)17: // Keycode für Alt?
                    alt_pressed = true;
                    break;
            }

            if (alt_pressed && e.KeyCode == Keys.Q) // fail!
                InputEvent_CharEntered(sender, new CharacterEventArgs('@', 0));

            if (e.KeyCode == Keys.Back && s.Length > 0)
                s = s.Remove(s.Length - 1, 1);
            if (e.KeyCode == Keys.Enter)
            {
                activated_field++;
                if (activated_field > 1)
                {
                    activated_field = -1;
                    OnSubmit();
                }
                return;
            }

            if (activated_field == 0)
                user_mail = s;
            else if (activated_field == 1)
                user_pass = s;
        }

        void scr_Accepted(object sender, EventArgs e)
        {
            ExitScreen();
        }

        void InputEvent_CharEntered(object sender, CharacterEventArgs e)
        {
            const string valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 !()=üöäüÜÖÄß?-_@.^/,";

            if (activated_field == -1) return;
            if (maxlen > -1 && (activated_field == 0 ? user_mail : user_pass).Length > maxlen) return;
            if (valid_chars.IndexOf(e.Character) == -1) return;

            if (activated_field == 0)
                user_mail += e.Character;
            else if (activated_field == 1)
                user_pass += e.Character;

        }

        void OnSubmit()
        {
            MessageBoxScreen scr;
            if (Highscore.LoginUser(user_mail.Replace("(at)", "@"), user_pass, keep_login))
            {
                scr = new MessageBoxScreen("Du wurdest erfolgreich eingeloggt!", false);
                scr.Accepted += new EventHandler<EventArgs>(scr_Accepted);
                scr.Cancelled += new EventHandler<EventArgs>(scr_Accepted);
            }
            else
            {
                scr = new MessageBoxScreen("Fehler beim Login!\nBitte überprüfe deine Daten.", false);
            }
            ScreenManager.AddScreen(scr);
        }

        public override void Activate(bool instancePreserved)
        {
            if (!instancePreserved)
            {
                if (content == null)
                    content = new ContentManager(ScreenManager.Game.Services, "Content");

                font = content.Load<SpriteFont>("SegoeUIMono");
                smallfont = content.Load<SpriteFont>("Smallfont");
                backgroundTexture = content.Load<Texture2D>("Menu\\background");
                checkboxChecked = content.Load<Texture2D>("Menu\\cb_checked");
                checkboxUnchecked = content.Load<Texture2D>("Menu\\cb_unchecked");
                backgroundLayer = new Texture2D(ScreenManager.Game.GraphicsDevice, 1, 1);
                backgroundLayer.SetData<Color>(new Color[] { new Color(0, 0, 20, 200) });

                ScreenManager.Game.ResetElapsedTime();

                keep_login = true;
                user_mail = "";
                user_pass = "";
            }
        }

        public override void Unload()
        {
            content.Unload();
        }

        public override void HandleInput(GameTime gameTime, InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            KeyboardState keyboardState = input.CurrentKeyboardState;
            GamePadState gamePadState = input.CurrentGamePadState;
            MouseState mouseState = input.CurrentMouseState;

            if (inputExit.Evaluate(input))
                ExitScreen();

            if (input.IsLeftClick())
            {
                if (new Rectangle(100, 240, 300, 20).Contains(mouseState.X, mouseState.Y))
                    keep_login = !keep_login;

                if (new Rectangle(100, 200, 300, 20).Contains(mouseState.X, mouseState.Y))
                    activated_field = 0;
                else if (new Rectangle(100, 220, 300, 20).Contains(mouseState.X, mouseState.Y))
                    activated_field = 1;
                else
                    activated_field = -1;

                if (buttonOkHover)
                    OnSubmit();
                else if (buttonCancelHover)
                    ExitScreen();
            }
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                   bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            if (IsActive)
            {
                GraphicsDevice graphics = ScreenManager.GraphicsDevice;
                MouseState state = Mouse.GetState();

                if (blink_delay <= 0)
                {
                    blink_delay = 0.5f;
                    blink_state = !blink_state;
                }
                blink_delay -= (float)gameTime.ElapsedGameTime.TotalSeconds;

                buttonOkHover = buttonCancelHover = false;
                if (new Rectangle(100, 300, 100, 20).Contains(state.X, state.Y))
                    buttonOkHover = true;
                else if (new Rectangle(250, 300, 100, 20).Contains(state.X, state.Y))
                    buttonCancelHover = true;
            }
        }

        public override void Draw(GameTime gameTime)
        {
            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                               Color.CornflowerBlue, 0, 0);

            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);

            spriteBatch.Begin();

            spriteBatch.Draw(backgroundTexture, fullscreen,
                             new Color(TransitionAlpha, TransitionAlpha, TransitionAlpha));
            spriteBatch.Draw(backgroundLayer, new Rectangle(80, 80, viewport.Width - 160, 260),
                             Color.White);

            spriteBatch.DrawString(font, "Gib bitte deine Zugangsdaten von " + Highscore.HighscoreName + " ein.", new Vector2(100, 100), Color.White);
            spriteBatch.DrawString(font, "Diese werden benötigt, um den Highscore mit\ndeinem Account zu verknüpfen", new Vector2(100, 120), Color.White);
            spriteBatch.DrawString(smallfont, "(Bitte (at) statt @ verwenden!)", new Vector2(100, 180), Color.White);

            spriteBatch.DrawString(font, "Email:", new Vector2(100, 200), Color.White);
            spriteBatch.DrawString(font, "Passwort:", new Vector2(100, 220), Color.White);
            spriteBatch.DrawString(font, "Login merken?", new Vector2(100, 240), Color.White);

            spriteBatch.DrawString(font, user_mail, new Vector2(250, 200), Color.White);
            spriteBatch.DrawString(font, user_pass, new Vector2(250, 220), Color.White);
            spriteBatch.Draw(keep_login ? checkboxChecked : checkboxUnchecked, new Rectangle(250, 245, 20, 20), new Rectangle(0, 0, 42, 42), Color.White);

            spriteBatch.DrawString(font, "OK", new Vector2(100, 300), buttonOkHover ? Color.Yellow : Color.White);
            spriteBatch.DrawString(font, "Abbrechen", new Vector2(250, 300), buttonCancelHover ? Color.Yellow : Color.White);

            if (activated_field >= 0 && blink_state)
            {
                float x = font.MeasureString((activated_field == 0) ? user_mail : user_pass).X + 251;
                spriteBatch.DrawString(font, "|", new Vector2(x, (activated_field == 0) ? 200 : 220), Color.White);
            }

            spriteBatch.End();
        }
    }
}
